home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
SGI Developer Toolbox 6.1
/
SGI Developer Toolbox 6.1 - Disc 4.iso
/
src
/
haeberli
/
libgutil
/
tmeshobj.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-08-01
|
5KB
|
253 lines
/*
* Copyright 1991, 1992, 1993, 1994, Silicon Graphics, Inc.
* All Rights Reserved.
*
* This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
* the contents of this file may not be disclosed to third parties, copied or
* duplicated in any form, in whole or in part, without the prior written
* permission of Silicon Graphics, Inc.
*
* RESTRICTED RIGHTS LEGEND:
* Use, duplication or disclosure by the Government is subject to restrictions
* as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
* and Computer Software clause at DFARS 252.227-7013, and/or in similar or
* successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
* rights reserved under the Copyright Laws of the United States.
*/
/*
* tmeshobj-
* Convert an sgi obj into triangle meshes.
*
* Paul Haeberli - 1990
*/
#include "sgiobj.h"
#include "mesh.h"
static sgiobj *outobj;
static long *outptr;
static int np;
static int vcount;
static int lastcmd;
static long *countpos;
/*
* hashlongs -
* this returns an integer hash value for an array of longs.
*
*/
static long hashlongs(buf,n)
long *buf;
{
long hash;
hash = 0;
while(n--)
hash = (273*hash)+(*buf++);
return hash&0x7fffffff;
}
/*
* newcommand -
*
* is used to create a triangle meshed sgo format object
* in memory.
*/
static newcommand(op)
long op;
{
if(op == OP_BGNTMESH && lastcmd == OP_ENDTMESH && vcount == 0) {
outptr[-2] = OP_ENDBGNTMESH;
return;
}
if(vcount>0) {
*countpos = vcount;
vcount = 0;
}
lastcmd = op;
*outptr++ = op;
countpos = outptr;
outptr++;
}
/* initialization functions follow */
/*
* out_ambegin -
*
* the mesh package calls this rountine with the total number of
* verticies and triangles in the tmeshed object.
*/
static void out_ambegin(nverts,ntris)
int nverts, ntris;
{
int maxlongs;
maxlongs = 2+(nverts*PNTLONGS)+(3*np*5)+1;
outobj = (sgiobj *)newtmeshobj(maxlongs);
outptr = outobj->data;
*outptr++ = PNTLONGS*nverts;
vcount = 0;
lastcmd = 0;
}
/*
* out_amend -
*
* the mesh package calls this rountine as the very last thing
* it does.
*/
static void out_amend()
{
outobj->nlongs = outptr-outobj->data;
}
/* comparison functions follow */
/*
* out_amhashvert -
*
* this function will take all the interesting data for a
* vertex and return an integer hash value. this is used to
* make vertex comparison operations much more efficient
* for large objects.
*/
static int out_amhashvert(long v)
{
return hashlongs(v,9);
}
/*
* out_amvertsame -
*
* this function will take all the interesting data for a
* vertex and return an value of 1 if the verticies are identical
* and 0 if they differ.
*/
static int out_amvertsame(long l1, long l2)
{
float *v1, *v2;
v1 = (float *)l1;
v2 = (float *)l2;
if(v1[0] != v2[0]) return 0;
if(v1[1] != v2[1]) return 0;
if(v1[2] != v2[2]) return 0;
if(v1[3] != v2[3]) return 0;
if(v1[4] != v2[4]) return 0;
if(v1[5] != v2[5]) return 0;
if(v1[6] != v2[6]) return 0;
if(v1[7] != v2[7]) return 0;
if(v1[8] != v2[8]) return 0;
return 1;
}
/* output functions follow */
/*
* out_amvertdata -
*
* this function will be called once for each vertex in the
* tmeshed object. The order of these verticies are used
* by out_amvert below.
*/
static void out_amvertdata(long fptr)
{
bcopy(fptr,outptr,9*sizeof(long));
outptr += PNTLONGS;
}
/*
* out_ambgntmesh -
*
* this function indicates the start of a GL tmesh.
*/
static void out_ambgntmesh(void)
{
newcommand(OP_BGNTMESH);
}
/*
* out_amendtmesh -
*
* this function indicates the end of a GL tmesh.
*/
static void out_amendtmesh(void)
{
newcommand(OP_ENDTMESH);
}
/*
* out_amswaptmesh -
*
* this function indicates a swap tmesh.
*/
static void out_amswaptmesh(void)
{
newcommand(OP_SWAPTMESH);
}
/*
* out_amvert -
*
* this function indicates the index of a vertex to output
* inside a tmesh.
*/
static void out_amvert(long index)
{
*outptr++ = PNTLONGS*index*sizeof(long);
vcount++;
}
/*
* tmeshobj -
* this takes an sgiobj that is stored as a list of trianlges
* and returns a triangle mesh format object.
*/
sgiobj *tmeshobj(obj)
sgiobj *obj;
{
int poly, i;
float *fptr;
Meshobj *mc;
/* initialize the meshing package */
mc = newMeshobj( out_ambegin,
out_amend,
out_amhashvert,
out_amvertsame,
out_amvertdata,
out_ambgntmesh,
out_amendtmesh,
out_amswaptmesh,
out_amvert);
/* indicate start of triangles */
in_ambegin(mc);
np = (obj->nlongs/PNTLONGS)/3;
fptr = (float*)obj->data;
for(poly=0; poly<np; poly++) {
/* start a triangle */
in_amnewtri(mc);
/* push out the vertex addresses */
for(i=0; i<3; i++) {
in_amvert(mc,(long)fptr);
fptr += PNTLONGS;
}
}
/* indicate end of the triangles */
in_amend(mc);
/* free storage allocated for meshing */
freeMeshobj(mc);
return outobj;
}